/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package com.googlecode.ivybeans.module.nodes;

import com.googlecode.ivybeans.facade.ArtifactInfo;
import com.googlecode.ivybeans.module.FileHelper;
import com.googlecode.ivybeans.module.IvyDescriptorHelper;
import com.googlecode.ivybeans.module.IvyLibraryController;
import com.googlecode.ivybeans.module.resources.ResourcesAccess;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.spi.java.project.support.ui.PackageView;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;

class ArtifactNode extends AbstractNode {

    private ArtifactInfo artifactInfo;
    private Project project;
    private final static String LIBRARIES_ICON = "org/netbeans/modules/java/j2seproject/ui/resources/libraries.gif"; //NOI18N
    private final static String SOURCE_BADGE_ICON = "com/googlecode/ivybeans/module/resources/DependencySrcIncluded.png"; //NOI18N
    private final static String JAVADOC_BADGE_ICON = "com/googlecode/ivybeans/module/resources/DependencyJavadocIncluded.png"; //NOI18N
    private final static String MISSING_JAR_BADGE_ICON = "com/googlecode/ivybeans/module/resources/ResourceNotIncluded.gif"; //NOI18N

     private static String toolTipJavadoc = "<img src=\"" + ArtifactNode.class.getClassLoader().getResource(JAVADOC_BADGE_ICON) + "\">&nbsp;" //NOI18N
            + NbBundle.getMessage(ArtifactNode.class, "ICON_JavadocBadge");//NOI18N
    private static String toolTipSource = "<img src=\"" + ArtifactNode.class.getClassLoader().getResource(SOURCE_BADGE_ICON) + "\">&nbsp;" //NOI18N
            + NbBundle.getMessage(ArtifactNode.class, "ICON_SourceBadge");//NOI18N
    private static String toolTipMissing = "<img src=\"" + ArtifactNode.class.getClassLoader().getResource(MISSING_JAR_BADGE_ICON) + "\">&nbsp;" //NOI18N
            + NbBundle.getMessage(ArtifactNode.class, "ICON_MissingBadge");//NOI18N
    
    
    public ArtifactNode(ArtifactInfo artifactInfo, Project project) {
        super(new JarContentFilterChildren(PackageView.createPackageView(new ArtifactSourceGroup(artifactInfo))));
        this.project = project;
        this.artifactInfo = artifactInfo;
        setIconBaseWithExtension(LIBRARIES_ICON);
    }

    @Override
    public String getDisplayName() {
        return artifactInfo.getName() + " " + artifactInfo.getVersion();
    }

    @Override
    public String getName() {
        return artifactInfo.getName() + " " + artifactInfo.getVersion();
    }

    @Override
    public Image getIcon(int param) {
        Image retValue;
        retValue = super.getIcon(param);
        if (artifactInfo.hasJavadoc()) {
            Image ann = ImageUtilities.loadImage(JAVADOC_BADGE_ICON); //NOI18N
            ann = ImageUtilities.addToolTipToImage(ann, toolTipJavadoc);                
            retValue = ImageUtilities.mergeImages(retValue, ann, 12, 0);
        }
        if (artifactInfo.hasSource()) {
            Image ann = ImageUtilities.loadImage(SOURCE_BADGE_ICON); //NOI18N
            ann = ImageUtilities.addToolTipToImage(ann, toolTipSource);
            retValue = ImageUtilities.mergeImages(retValue, ann, 12, 8);
        }
        if (!artifactInfo.hasJar()) {
            Image ann = ImageUtilities.loadImage(MISSING_JAR_BADGE_ICON); //NOI18N
            ann = ImageUtilities.addToolTipToImage(ann, toolTipMissing);
            retValue = ImageUtilities.mergeImages(retValue, ann, 0, 0);//NOI18N
        }
        return retValue;
    }

    @Override
    public Image getOpenedIcon(int type) {
        return getIcon(type);
    }

    @Override
    public Action[] getActions(boolean context) {
        return new Action[]{new RemoveOrExcludeLibraryAction()};
    }

    private class RemoveOrExcludeLibraryAction extends AbstractAction {

        public RemoveOrExcludeLibraryAction() {
            putValue(Action.NAME, NbBundle.getMessage(ResourcesAccess.class, "BTN_Remove_Library"));
        }

        public void actionPerformed(ActionEvent event) {
            IvyLibraryController ilc = project.getLookup().lookup(IvyLibraryController.class);
            IvyDescriptorHelper.getInstance().removeDependency(FileHelper.getInstance().toFO(ilc.getDescriptorFile()), artifactInfo.getOrganisation(), artifactInfo.getName());
        }
    }

    private static class ArtifactSourceGroup implements SourceGroup {

        private ArtifactInfo artInfo;

        ArtifactSourceGroup(ArtifactInfo artInfo) {
            this.artInfo = artInfo;
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
        }

        public boolean contains(FileObject file) throws IllegalArgumentException {
            return true;
        }

        public String getDisplayName() {
            return artInfo.getName();
        }

        public Icon getIcon(boolean opened) {
            return null;
        }

        public String getName() {
            return artInfo.getName();
        }

        public FileObject getRootFolder() {
            File file = (artInfo.getSourceFile() != null) ? artInfo.getSourceFile() : artInfo.getJarFile();
            if (file != null) {
                FileObject fo = FileUtil.toFileObject(FileUtil.normalizeFile(file));
                if (fo != null) {
                    return FileUtil.getArchiveRoot(fo);
                }
            }
            return null;
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
        }
    }

    private static class JarContentFilterChildren extends FilterNode.Children {

        JarContentFilterChildren(Node orig) {
            super(orig);
        }

        @Override
        protected Node copyNode(Node node) {
            return new JarFilterNode(node);
        }
    }

    private static class JarFilterNode extends FilterNode {

        JarFilterNode(Node original) {
            super(original, new JarContentFilterChildren(original));
        }
    }
}
